package com.ruoyi.system.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.common.constant.ResultConstants;
import com.ruoyi.common.enums.TxnType;
import com.ruoyi.common.exception.BusinessException;
import com.ruoyi.common.support.Convert;
import com.ruoyi.common.utils.BigDecimalUtil;
import com.ruoyi.common.utils.MessageUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.system.domain.WdyConsume;
import com.ruoyi.system.domain.WdyTxnHistory;
import com.ruoyi.system.domain.WdyUser;
import com.ruoyi.system.mapper.WdyConsumeMapper;
import com.ruoyi.system.service.IWdyConsumeService;
import com.ruoyi.system.service.IWdyTxnHistoryService;
import com.ruoyi.system.service.IWdyUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.List;

/**
 * 消费 服务层实现
 * 
 * @author ruoyi
 * @date 2020-08-31
 */
@Service
public class WdyConsumeServiceImpl extends ServiceImpl<WdyConsumeMapper, WdyConsume> implements IWdyConsumeService
{
	@Autowired
	private IWdyUserService wdyUserService;

	@Autowired
	private IWdyTxnHistoryService wdyTxnHistoryService;
	/**
     * 查询消费信息
     * 
     * @param id 消费ID
     * @return 消费信息
     */
    @Override
	public WdyConsume selectWdyConsumeById(Long id)
	{
	    return baseMapper.selectWdyConsumeById(id);
	}
	
	/**
     * 查询消费列表
     * 
     * @param wdyConsume 消费信息
     * @return 消费集合
     */
	@Override
	public List<WdyConsume> selectWdyConsumeList(WdyConsume wdyConsume)
	{
	    return baseMapper.selectWdyConsumeList(wdyConsume);
	}
	
    /**
     * 新增消费
     * 
     * @param wdyConsume 消费信息
     * @return 结果
     */
	@Override
	public int insertWdyConsume(WdyConsume wdyConsume)
	{
	    return baseMapper.insertWdyConsume(wdyConsume);
	}
	
	/**
     * 修改消费
     * 
     * @param wdyConsume 消费信息
     * @return 结果
     */
	@Override
	public int updateWdyConsume(WdyConsume wdyConsume)
	{
	    return baseMapper.updateWdyConsume(wdyConsume);
	}

	/**
     * 删除消费对象
     * 
     * @param ids 需要删除的数据ID
     * @return 结果
     */
	@Override
	public int deleteWdyConsumeByIds(String ids)
	{
		return baseMapper.deleteWdyConsumeByIds(Convert.toStrArray(ids));
	}

	@Transactional(rollbackFor = Exception.class)
	@Override
	public void consume(WdyConsume consume) {
		if(StringUtils.isEmpty(consume.getUserId())) {
			throw new BusinessException(ResultConstants.FI1000, "用户id" + MessageUtils.message("not.null"));
		}

		if(StringUtils.isEmpty(consume.getConsumeId())) {
			throw new BusinessException(ResultConstants.FI1000, "consumeId" + MessageUtils.message("not.null"));
		}


		if(StringUtils.isEmpty(consume.getRemark())) {
			throw new BusinessException(ResultConstants.FI1000, "remark" + MessageUtils.message("not.null"));
		}

		BigDecimal vcAmount = consume.getVcAmount();
		if(vcAmount == null) {
			throw new BusinessException(ResultConstants.FI1000, "vcAmount" + MessageUtils.message("not.null"));
		}
		vcAmount = BigDecimalUtil.getP4Decimal(vcAmount);
		consume.setVcAmount(vcAmount);

		BigDecimal vcConsumeAmount = consume.getVcConsumeAmount();
		if(vcConsumeAmount == null) {
			throw new BusinessException(ResultConstants.FI1000, "vcConsumeAmount" + MessageUtils.message("not.null"));
		}
		vcConsumeAmount = BigDecimalUtil.getP4Decimal(vcConsumeAmount);
		consume.setVcConsumeAmount(vcConsumeAmount);

		BigDecimal vcWithdrawAmount = consume.getVcWithdrawAmount();
		if(vcWithdrawAmount == null) {
			throw new BusinessException(ResultConstants.FI1000, "vcWithdrawAmount" + MessageUtils.message("not.null"));
		}
		vcWithdrawAmount = BigDecimalUtil.getP4Decimal(vcWithdrawAmount);
		consume.setVcWithdrawAmount(vcWithdrawAmount);

		if(vcAmount.compareTo(BigDecimal.ZERO) < 0 || vcConsumeAmount.compareTo(BigDecimal.ZERO) < 0
				|| vcWithdrawAmount.compareTo(BigDecimal.ZERO) < 0) {
			throw new BusinessException(ResultConstants.FI1000, "amount" + MessageUtils.message("param.error"));
		}

		if(vcAmount.compareTo(BigDecimal.ZERO) == 0 && vcConsumeAmount.compareTo(BigDecimal.ZERO) == 0
				&& vcWithdrawAmount.compareTo(BigDecimal.ZERO) == 0) {
			throw new BusinessException(ResultConstants.FI1000, "amount" + MessageUtils.message("param.error"));
		}

		QueryWrapper<WdyUser> queryWrapper = new QueryWrapper<>();
		queryWrapper.select("user_id", "vc_amount", "vc_consume_amount", "vc_withdraw_amount", "version");
		queryWrapper.eq("user_id", consume.getUserId());
		WdyUser user = wdyUserService.getOne(queryWrapper);

		if(user == null) {
			throw new BusinessException(ResultConstants.FI1000, "userId" + MessageUtils.message("param.error"));
		}

		if(vcAmount.compareTo(user.getVcAmount()) > 0) {
			throw new BusinessException(ResultConstants.FI1000, "vcAmount余额不足");
		}

		if(vcConsumeAmount.compareTo(user.getVcConsumeAmount()) > 0) {
			throw new BusinessException(ResultConstants.FI1000, "vcConsumeAmount余额不足");
		}

		if(vcWithdrawAmount.compareTo(user.getVcWithdrawAmount()) > 0) {
			throw new BusinessException(ResultConstants.FI1000, "vcWithdrawAmount余额不足");
		}

		UpdateWrapper<WdyUser> updateWrapper = new UpdateWrapper<>();
		updateWrapper.eq("user_id", user.getUserId());
		updateWrapper.eq("version", user.getVersion());
		updateWrapper.set("vc_amount", BigDecimalUtil.subtract(user.getVcAmount(), vcAmount));
		updateWrapper.set("vc_consume_amount", BigDecimalUtil.subtract(user.getVcConsumeAmount(), vcConsumeAmount));
		updateWrapper.set("vc_withdraw_amount", BigDecimalUtil.subtract(user.getVcWithdrawAmount(), vcWithdrawAmount));
		if(!wdyUserService.update(updateWrapper)) {
			throw new BusinessException(ResultConstants.FI2007, "系统繁忙，请稍后重试");
		}

		this.save(consume);

		if(vcAmount.compareTo(BigDecimal.ZERO) > 0) {
			WdyTxnHistory txnHistory = new WdyTxnHistory();
			txnHistory.setUserId(user.getUserId());
			txnHistory.setTxnId(String.valueOf(consume.getId()));
			txnHistory.setTxnAmount(vcAmount.negate());
			txnHistory.setTxnType(TxnType.CONSUME_VC.getCode());
			txnHistory.setAmountType(TxnType.CONSUME_VC.getAmountType().getCode());
			txnHistory.setTxnDesc(consume.getRemark());
			wdyTxnHistoryService.save(txnHistory);
		}

		if(vcConsumeAmount.compareTo(BigDecimal.ZERO) > 0) {
			WdyTxnHistory txnHistory = new WdyTxnHistory();
			txnHistory.setUserId(user.getUserId());
			txnHistory.setTxnId(String.valueOf(consume.getId()));
			txnHistory.setTxnAmount(vcConsumeAmount.negate());
			txnHistory.setTxnType(TxnType.CONSUME_VC_CONSUME.getCode());
			txnHistory.setAmountType(TxnType.CONSUME_VC_CONSUME.getAmountType().getCode());
			txnHistory.setTxnDesc(consume.getRemark());
			wdyTxnHistoryService.save(txnHistory);
		}

		if(vcWithdrawAmount.compareTo(BigDecimal.ZERO) > 0) {
			WdyTxnHistory txnHistory = new WdyTxnHistory();
			txnHistory.setUserId(user.getUserId());
			txnHistory.setTxnId(String.valueOf(consume.getId()));
			txnHistory.setTxnAmount(vcWithdrawAmount.negate());
			txnHistory.setTxnType(TxnType.CONSUME_VC_WITHDRAW.getCode());
			txnHistory.setAmountType(TxnType.CONSUME_VC_WITHDRAW.getAmountType().getCode());
			txnHistory.setTxnDesc(consume.getRemark());
			wdyTxnHistoryService.save(txnHistory);
		}
	}

}
